#ifndef __Ogre7zFile_H__
#define __Ogre7zFile_H__
#pragma once

// Include stuff
#include "Ogre7zPrerequisites.h"
#include <7z.h>
#include <7zFile.h>

namespace Ogre
{
	// Per-class allocator
	typedef Ogre::GeneralAllocatedObject SevenZipFileAlloc;

	/**
	 * @brief Specialisation of this class is work with 7zip file
	 */
	class SevenZipFile : public SevenZipFileAlloc
	{
	public:
		/**
		 * @brief Standart constructor
		 */
		SevenZipFile( const String& name );

		/**
		 * @brief Default destructor
		 */
		~SevenZipFile();

		/**
		 * @brief Loading this 7zip archive
		 * @note Throw an exception if error occured
		 */
		void load();

		/**
		 * @brief Unloading 7zip archive
		 */
		void unload();

		/**
		 * @brief Returns whther this file is loaded
		 */
		bool getIsLoaded() const;

		/**
		 * @brief Retrieves the extract data of this archive
		 */
		const CSzArEx& getExtractData() const;

		/**
		 * @brief Retrieves a whole number of this arvhive files 
		 */
		size_t getNumFiles() const;

		/**
		 * @brief Retrieves the CSzFileItem for file specified
		 */
		const CSzFileItem* getFileItem( size_t index ) const;

		/**
		 * @brief Retrieves the name of file specified
		 */
		String getFileName( size_t index ) const;

		/**
		 * @brief Retrieves the name of file specified
		 */
		void getFileName( size_t index, String& name ) const;

		/**
		 * @biref Retrieves the modufucation time for file specified
		 */
		time_t getModifiedTime( size_t index ) const;

		/**
		 * @brief Retrieves the size of the file
		 */
		size_t getFileSize( size_t index ) const;

		/**
		 * @brief Returns whether specified file is a directory
		 */
		bool getIsDirectory( size_t index ) const;

		/**
		 * @brief Retrieves the index of file with name specified
		 * @return Returns the file index if file exist. Otherwise return (-1)
		 */
		size_t getFileIndex( const String& name ) const;

		/**
		 * @brief Exptacting file specified to utput buffer
		 */
		SRes extract( size_t index, size_t& offset, size_t& outSizeProcessed );

		/**
		 * @brief Retrieves the output buffer 
		 */
		const Byte* getOutBuffer() const;

	protected:
		/// The name of this file
		String mName;
		/// Is archive loaded?
		bool mLoaded;
		/// 7zip extract block index. Can have any value before first call (if mOutBuffer = 0)
		UInt32 mBlockIndex;
		/// The extract output buffer. Must be 0 before first call for each new archive
		Byte* mOutBuffer;
		/// The size in bytes of oupput buffer. Can have any value before first call (if mOutBuffer = 0)
		size_t mOutBufferSize;
		// The instance of 7zip archive input stream
		CFileInStream mArchiveStream;
		// The 7zip look stream;
		CLookToRead mLookStream;
		// The archive extract data
		CSzArEx mDb;
	};

} // end of namespace Ogre

#endif // include guard, end of #ifndef __Ogre7zFile_H__
